﻿using JT809.GpsRedisConsumer.Common;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using SqlSugar;
using SqlSugar.IOC;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace JT809.GpsRedisConsumer.Models
{
    /// <summary>
    /// 注释参考JT809VehiclePositionProperties
    /// </summary>
    [SplitTable(SplitType.Day)]//按年分表 （自带分表支持 年、季、月、周、日）
    [SugarTable("gpsInfoPro{year}{month}{day}")]//3个变量必须要有，这么设计为了兼容开始按年，后面改成按月、按日

    public class GpsInfoPro
    {
        [SugarColumn(IsPrimaryKey = true)]
        public long Id { get; set; }
        public string Vno { get; set; }
        public int VColor { get; set; }
        public string VColor2
        {
            get
            {
                return VColor switch { 1 => "蓝色", 2 => "黄色", 3 => "黑色", 4 => "白色", 9 => "其他", _ => "未知" };
            }
        }
        public string FromChannel { set; get; }
        /// <summary>
        /// 定位信息是否使用国家测绘局批准的地图保密插件进行加密。0未加密,1已加密
        /// </summary>
        public int Encrypt { get; set; }
        public long GpsTime { get; set; }

        [JsonConverter(typeof(JsonDateTimeConvert))]
        //[SugarColumn(IsOnlyIgnoreUpdate = true)]
        [SplitField] //分表字段 在插入的时候会根据这个字段插入哪个表，在更新删除的时候用这个字段找出相关表
        public DateTime GpsTime2
        {
            get
            {
                if (this.GpsTime < 0)
                {
                    return new DateTime(1900, 1, 1);
                }
                else
                {
                    return DateTimeUtil.TimeStampToDateTime(this.GpsTime);
                }
            }
        }
        /// <summary>
        /// 经度，单位为 1*10^-6 度。
        /// </summary>
        public long Lon { get; set; }
        public double Lon2
        {
            get
            {
                return 0.000001d * Lon;
            }
        }
        /// <summary>
        /// 纬度，单位为 1*10^-6 度。
        /// </summary>
        public long Lat { get; set; }
        public double Lat2
        {
            get
            {
                return 0.000001d * Lat;
            }
        }
        /// <summary>
        /// 速度，指卫星定位车载终端设备上传的行车速度信息，为必填项。单位为千米每小时（km/h）。
        /// </summary>
        public int Vec1 { get; set; }
        /// <summary>
        /// 行驶记录速度，指车辆行驶记录设备上传的行车速度 信息，为必填项。单位为千米每小时（km/h）。
        /// </summary>
        public int Vec2 { get; set; }
        /// <summary>
        /// 车辆当前总里程数，值车辆上传的行车里程数。单位单位为千米（km）
        /// </summary>
        public int Vec3 { get; set; }
        /// <summary>
        /// 方向，0-359，单位为度（。），正北为 0，顺时针。
        /// </summary>
        public int Direction { get; set; }
        /// <summary>
        /// 海拔高度，单位为米（m）。
        /// </summary>
        public int Altitude { get; set; }
        /// <summary>
        /// 车辆状态，二进制表示，B31B30B29。。。。。。B2B1B0.具体定义按照 JT/T808-2019 中表 24 的规定
        /// </summary>
        public int State { get; set; }
        public string State2
        {
            get
            {
                return Convert.ToString(this.State, 2).PadLeft(32, '0');
            }
        }
        /// <summary>
        /// 报警状态，二进制表示，0 标识正常，1 表示报警： B31B30B29 。。。。。。 B2B1B0.具 体 定 义 按 照JT/T808-2019 中表 25 的规定
        /// </summary>
        public int Alarm { get; set; }
        public string Alarm2
        {
            get
            {
                return Convert.ToString(this.Alarm, 2).PadLeft(32, '0');
            }
        }

        [JsonConverter(typeof(JsonDateTimeConvert))]
        [SugarColumn(InsertServerTime = true)]//设置为可空字段 (更多用法看文档 迁移)
        public DateTime CreateTime { get; set; } = DateTime.Now;

        [SugarColumn(InsertSql = "1")]
        public int Status { get; set; } = 1;
    }

    public class JsonDateTimeConvert : IsoDateTimeConverter
    {
        public JsonDateTimeConvert() : base()
        {
            DateTimeFormat = "yyyy-MM-dd HH:mm:ss";
        }
    }

    [SplitTable(SplitType.Day)]//按年分表 （自带分表支持 年、季、月、周、日）
    [SugarTable("gpsInfo{year}{month}{day}")]//3个变量必须要有，这么设计为了兼容开始按年，后面改成按月、按日
    public class GpsInfo
    {
        [SugarColumn(IsPrimaryKey = true)]
        public long gpsId { get; set; }
        public int VehicleId { get; set; }
        [SugarColumn(IsNullable = true)]
        public string SimNo { get; set; }
        public string PlateNo { get; set; }
        public int Signal { get; set; }
        [SplitField] //分表字段 在插入的时候会根据这个字段插入哪个表，在更新删除的时候用这个字段找出相关表
        public DateTime SendTime { get; set; }
        public double Longitude { get; set; }
        public double Latitude { get; set; }
        public double Velocity { get; set; }
        [SugarColumn(IsNullable = true)]
        public string Location { get; set; }
        public int Direction { get; set; }
        public string Status { get; set; }
        public string AlarmState { get; set; }
        public double Mileage { get; set; }
        //油位数据
        [SugarColumn(IsNullable = true)]
        public string FuelLevelData { get; set; }
        //油量数据
        [SugarColumn(IsNullable = true)]
        public string FuelData { get; set; }
        public double Gas { get; set; }
        public double RecordVelocity { get; set; }
        public double Altitude { get; set; }
        public bool? Valid
        {
            get
            {
                if (string.IsNullOrEmpty(Status) == false && Status.Length == 32)
                {
                    if ((Convert.ToInt32(Status, 2) & (int)VehicleState.ACCOpen) == (int)VehicleState.ACCOpen)
                    {
                        return true;
                    }
                    else
                    {
                        return false;
                    }
                }
                else
                {
                    return null;
                }
            }
        }
        public string RunStatus
        {
            get
            {
                if (string.IsNullOrEmpty(Status) == false && Status.Length == 32)
                {
                    //if (Convert.ToInt32(Status, 2) & (int)VehicleState.OperatingState) == (int)VehicleState.OperatingState)
                    if ((Convert.ToInt32(Status, 2) & (int)VehicleState.OperatingState) >> 4 == 0)
                    {
                        return "运营状态";
                    }
                    else
                    {
                        return "停运状态";
                    }
                }
                else
                {
                    return "";
                }
            }
        }
        public int TenantId { get; set; } = 0;
        [JsonConverter(typeof(JsonDateTimeConvert))]
        [SugarColumn(InsertServerTime = true)]//设置为可空字段 (更多用法看文档 迁移)
        public DateTime CreateDate { get; set; } = DateTime.Now;
        [SugarColumn(InsertSql = "0")]
        public int Deleted { get; set; } = 0;
        public string Remark { get; set; } = "";
        public string Owner { get; set; } = "";
    }

    /// <summary>
    /// 车辆状态定义
    /// </summary>
    [Flags]
    public enum VehicleState : uint
    {
        /// <summary>
        /// ACC开和关标志
        /// 0：ACC 关；1： ACC 开
        /// </summary>
        ACCOpen = 1,

        /// <summary>
        /// 车辆定位标志
        /// 0：未定位；1：定位
        /// </summary>
        Location = 2,

        /// <summary>
        /// 0：北纬；1：南纬
        /// </summary>
        Latitude = 4,

        /// <summary>
        /// 0：东经；1：西经
        /// </summary>
        Longitude = 8,

        /// <summary>
        /// 运营状态
        /// 0：运营状态；1：停运状态
        /// </summary>
        OperatingState = 16,

        /// <summary>
        /// 0：经纬度未经保密插件加密；1：经纬度已经保密插件加密
        /// </summary>
        EncryptionPlugIn = 32,

        //...
        //2-6~2-9保留
        //...

        /// <summary>
        /// 0：车辆油路正常；1：车辆油路断开
        /// </summary>
        OilCircuit = 1024,

        /// <summary>
        /// 0：车辆电路正常；1：车辆电路断开
        /// </summary>
        Circuit = 2048,

        /// <summary>
        /// 0：车门解锁；1：车门加锁
        /// </summary>
        CarDoorLock = 4096

        //...
        //2-13~2-31保留
        //...
    }

    /// <summary>
    /// 报警状态定义
    /// </summary>
    [Flags]
    public enum AlarmState : uint
    {
        /// <summary>
        /// 紧急报警
        /// </summary>
        UrgentAlarm = 1,

        /// <summary>
        /// 超速报警
        /// </summary>
        OverSpeedAlarm = 2,

        /// <summary>
        /// 疲劳驾驶报警
        /// </summary>
        FatigueDrivingAlarm = 4,

        /// <summary>
        /// 预警
        /// </summary>
        EarlyWarningAlarm = 8,

        /// <summary>
        /// GNSS 模块发生故障报警
        /// </summary>
        GNSSModelFaultAlarm = 16,

        /// <summary>
        /// GNSS 天线未接或被剪断报警
        /// </summary>
        GNSSAntennaBreakAlarm = 32,

        /// <summary>
        /// GNSS 天线短路报警
        /// </summary>
        GNSSAntennaShortAlarm = 64,

        /// <summary>
        /// 终端主电源欠压报警
        /// </summary>
        TerminalMainPowerLowVoltageAlarm = 128,

        /// <summary>
        /// 终端主电源掉电报警
        /// </summary>
        TerminalMainPowerDownAlarm = 256,

        /// <summary>
        /// 终端LCD 或显示器故障报警
        /// </summary>
        TerminalLcdFaultAlarm = 512,

        /// <summary>
        /// TTS 模块故障报警
        /// </summary>
        TTSModelFaultAlarm = 1024,

        /// <summary>
        /// 摄像头故障报警
        /// </summary>
        CameraFaultAlarm = 2048,

        //...
        //2-12~2-17保留
        //...

        /// <summary>
        /// 当天累计驾驶超时报警
        /// </summary>
        TotalDrivingOvertimeDayAlarm = 262144,

        /// <summary>
        /// 超时停车报警
        /// </summary>
        ParkOvertimeAlarm = 524288,

        /// <summary>
        /// 进出区域报警
        /// </summary>
        InOutAreaAlarm = 1048576,

        /// <summary>
        /// 进出路线报警
        /// </summary>
        InOutLineAlarm = 2097152,

        /// <summary>
        /// 路段行驶时间不足/过长报警
        /// </summary>
        DrivingShorttimeOrOvertimeInOneSectionAlarm = 4194304,

        /// <summary>
        /// 路线偏离报警
        /// </summary>
        DrivingDeviationAlarm = 8388608,

        /// <summary>
        /// 车辆VSS 故障报警
        /// </summary>
        VehicleVSSFaultAlarm = 16777216,

        /// <summary>
        /// 车辆油量异常报警
        /// </summary>
        VehicleOilMassExceptionAlarm = 33554432,

        /// <summary>
        ///车辆被盗(通过车辆防盗器)报警
        /// </summary>
        BurglarAlarm = 67108864,

        /// <summary>
        /// 车辆非法点火报警
        /// </summary>
        IllegalityIgnitionAlarm = 134217728,

        /// <summary>
        /// 车辆非法位移报警
        /// </summary>
        IllegalityMoveAlarm = 268435456,

        /// <summary>
        /// 碰撞侧翻报警
        /// </summary>
        CrashAlarm = 536870912

        //...
        //2-30~2-31保留
        //...
    }

    #region 海宁老数据库结构
    [SplitTable(SplitType.Day)]//按年分表 （自带分表支持 年、季、月、周、日）
    [SugarTable("gpsInfo{year}{month}{day}")]//3个变量必须要有，这么设计为了兼容开始按年，后面改成按月、按日
    public class GpsInfoHN
    {
        [SugarColumn(IsPrimaryKey = true)]
        public long gpsId { get; set; }
        public int VehicleId { get; set; }
        [SugarColumn(IsNullable = true)]
        public string SimNo { get; set; }
        public string PlateNo { get; set; }
        public int Signal { get; set; }
        [SplitField] //分表字段 在插入的时候会根据这个字段插入哪个表，在更新删除的时候用这个字段找出相关表
        public DateTime SendTime { get; set; }
        public double Longitude { get; set; }
        public double Latitude { get; set; }
        public double Velocity { get; set; }
        [SugarColumn(IsNullable = true)]
        public string Location { get; set; }
        public int Direction { get; set; }
        public int Status { get; set; }
        public int AlarmState { get; set; }
        public double Mileage { get; set; }
        //油位数据
        [SugarColumn(IsNullable = true)]
        public string FuelLevelData { get; set; }
        //油量数据
        [SugarColumn(IsNullable = true)]
        public string FuelData { get; set; }
        public double Gas { get; set; }
        public double RecordVelocity { get; set; }
        public double Altitude { get; set; }
        public bool? Valid
        {
            get
            {
                if ((Status & (int)VehicleState.ACCOpen) == (int)VehicleState.ACCOpen)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
        }
        public string RunStatus
        {
            get
            {
                //if ((Status & (int)VehicleState.OperatingState) == (int)VehicleState.OperatingState)
                if ((Status & (int)VehicleState.OperatingState) >> 4 == 0)
                {
                    return "运营状态";
                }
                else
                {
                    return "停运状态";
                }
            }
        }
        public int TenantId { get; set; } = 0;
        [JsonConverter(typeof(JsonDateTimeConvert))]
        [SugarColumn(InsertServerTime = true)]//设置为可空字段 (更多用法看文档 迁移)
        public DateTime CreateDate { get; set; } = DateTime.Now;
        [SugarColumn(IsNullable = true)]
        public bool Deleted { get; set; } = false;
        public string Remark { get; set; } = "";
        public string Owner { get; set; } = "";
    }
    #endregion

    [SugarTable("GPSRealData")]
    public class GPSRealData
    {
        /// <summary>
        ///  
        ///</summary>
        [SugarColumn(ColumnName = "ID", IsPrimaryKey = true, IsIdentity = true)]
        public int Id { get; set; }
        /// <summary>
        ///  
        ///</summary>
        [SugarColumn(ColumnName = "VehicleId")]
        public int? VehicleId { get; set; } = 0;
        /// <summary>
        ///  
        ///</summary>
        [SugarColumn(ColumnName = "Status")]
        public string Status { get; set; }
        /// <summary>
        ///  
        ///</summary>
        [SugarColumn(ColumnName = "DepId")]
        public int? DepId { get; set; } = 0;
        /// <summary>
        ///  
        ///</summary>
        [SugarColumn(ColumnName = "Signal")]
        public int? Signal { get; set; } = 0;
        /// <summary>
        ///  
        ///</summary>
        [SugarColumn(ColumnName = "AlarmState")]
        public string AlarmState { get; set; }
        /// <summary>
        ///  
        ///</summary>
        [SugarColumn(ColumnName = "PlateNo")]
        public string PlateNo { get; set; }
        /// <summary>
        ///  
        ///</summary>
        [SugarColumn(ColumnName = "EnclosureId")]
        public int? EnclosureId { get; set; } = 0;
        /// <summary>
        ///  
        ///</summary>
        [SugarColumn(ColumnName = "EnclosureAlarm")]
        public int? EnclosureAlarm { get; set; } = 0;
        /// <summary>
        ///  
        ///</summary>
        [SugarColumn(ColumnName = "EnclosureType")]
        public int? EnclosureType { get; set; } = 0;
        /// <summary>
        ///  
        ///</summary>
        [SugarColumn(ColumnName = "OverSpeedAreaId")]
        public int? OverSpeedAreaId { get; set; } = 0;
        /// <summary>
        ///  
        ///</summary>
        [SugarColumn(ColumnName = "OverSpeedAreaType")]
        public int? OverSpeedAreaType { get; set; } = 0;
        /// <summary>
        ///  
        ///</summary>
        [SugarColumn(ColumnName = "RouteSegmentId")]
        public int? RouteSegmentId { get; set; } = 0;
        /// <summary>
        ///  
        ///</summary>
        [SugarColumn(ColumnName = "RunTimeOnRoute")]
        public int? RunTimeOnRoute { get; set; } = 0;
        /// <summary>
        ///  
        ///</summary>
        [SugarColumn(ColumnName = "RouteAlarmType")]
        public int? RouteAlarmType { get; set; } = 0;
        /// <summary>
        ///  
        ///</summary>
        [SugarColumn(ColumnName = "Location")]
        public string Location { get; set; } = "";
        /// <summary>
        ///  
        ///</summary>
        [SugarColumn(ColumnName = "SimNo")]
        public string SimNo { get; set; } = "";
        /// <summary>
        ///  
        ///</summary>
        [SugarColumn(ColumnName = "SendTime")]
        public DateTime? SendTime { get; set; }
        /// <summary>
        ///  
        ///</summary>
        [SugarColumn(ColumnName = "UpdateDate")]
        public DateTime? UpdateDate { get; set; } = DateTime.Now;
        /// <summary>
        ///  
        ///</summary>
        [SugarColumn(ColumnName = "Longitude")]
        public decimal? Longitude { get; set; }
        /// <summary>
        ///  
        ///</summary>
        [SugarColumn(ColumnName = "Latitude")]
        public decimal? Latitude { get; set; }
        /// <summary>
        ///  
        ///</summary>
        [SugarColumn(ColumnName = "Velocity")]
        public decimal? Velocity { get; set; }
        /// <summary>
        ///  
        ///</summary>
        [SugarColumn(ColumnName = "Direction")]
        public int? Direction { get; set; }
        /// <summary>
        ///  
        ///</summary>
        [SugarColumn(ColumnName = "Altitude")]
        public decimal? Altitude { get; set; }
        /// <summary>
        ///  
        ///</summary>
        [SugarColumn(ColumnName = "RecordVelocity")]
        public decimal? RecordVelocity { get; set; } = 0;
        /// <summary>
        ///  
        ///</summary>
        [SugarColumn(ColumnName = "Mileage")]
        public decimal? Mileage { get; set; }
        /// <summary>
        ///  
        ///</summary>
        [SugarColumn(ColumnName = "Gas")]
        public decimal? Gas { get; set; } = 0;
        /// <summary>
        ///  
        ///</summary>
        [SugarColumn(ColumnName = "Valid")]
        public bool? Valid { get; set; }
        /// <summary>
        ///  
        ///</summary>
        [SugarColumn(ColumnName = "Online")]
        public bool? Online { get; set; }
        /// <summary>
        ///  
        ///</summary>
        [SugarColumn(ColumnName = "FuelLevelData")]
        public string FuelLevelData { get; set; } = "";
        /// <summary>
        ///  
        ///</summary>
        [SugarColumn(ColumnName = "FuelData")]
        public string FuelData { get; set; } = "";
        /// <summary>
        ///  
        ///</summary>
        [SugarColumn(ColumnName = "CreateDate", IsOnlyIgnoreUpdate = true)]
        public DateTime? CreateDate { get; set; } = DateTime.Now;
    }
}
